home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / kernel / main / sun4.md / mainInit.c < prev   
Encoding:
C/C++ Source or Header  |  1992-12-19  |  11.8 KB  |  486 lines

  1. /* 
  2.  *  main.c --
  3.  *
  4.  *    The main program for Sprite: initializes modules and creates
  5.  *    system processes. Also creates a process to run the Init program.
  6.  *
  7.  * Copyright 1986 Regents of the University of California
  8.  * All rights reserved.
  9.  */
  10.  
  11. #ifndef lint
  12. static char rcsid[] = "$Header: /cdrom/src/kernel/Cvsroot/kernel/main/sun4.md/mainInit.c,v 9.12 92/08/10 20:44:18 mgbaker Exp $ SPRITE (Berkeley)";
  13. #endif /* !lint */
  14.  
  15. #include <sprite.h>
  16. #include <dbg.h>
  17. #include <dev.h>
  18. #include <net.h>
  19. #include <fs.h>
  20. #include <fsutil.h>
  21. #include <proc.h>
  22. #include <prof.h>
  23. #include <recov.h>
  24. #include <rpc.h>
  25. #include <sched.h>
  26. #include <sig.h>
  27. #include <sync.h>
  28. #include <sys.h>
  29. #include <timer.h>
  30. #include <vm.h>
  31. #include <machMon.h>
  32. #include <devAddrs.h>
  33. #include <mach.h>
  34. #include <stdlib.h>
  35. #include <main.h>
  36. #include <stdio.h>
  37. #include <bstring.h>
  38. #include <string.h>
  39. #include <dump.h>
  40. #include <fsrecov.h>
  41.  
  42. static void Init _ARGS_((void));
  43.  
  44. /*
  45.  *  Pathname of the Init program.
  46.  */
  47. #define INIT         "cmds/initsprite"
  48.  
  49. int main_PrintInitRoutines = FALSE;/* print out each routine as it's called. */
  50.  
  51. int main_PanicOK = 0;    /* Set to 1 if it's OK to panic. */
  52.  
  53. /*
  54.  *----------------------------------------------------------------------
  55.  *
  56.  * main --
  57.  *
  58.  *    All kernel modules are initialized by calling their *_Init()
  59.  *    routines. In addition, kernel processes are created to
  60.  *    handle virtual memory and rpc-specific stuff. The last process
  61.  *    created runs the `init' program.
  62.  *
  63.  * Results:
  64.  *    None.
  65.  *
  66.  * Side effects:
  67.  *    The whole system is initialized.
  68.  *
  69.  *----------------------------------------------------------------------
  70.  */
  71.  
  72. void
  73. main()
  74. {
  75.     Proc_PID    pid;
  76.     int        i;
  77.  
  78.     /*
  79.      * Initialize variables specific to a given kernel.  
  80.      * IMPORTANT: Only variable assignments and nothing else can be
  81.      *          done in this routine.
  82.      */
  83.     Main_InitVars();
  84.  
  85.     /*
  86.      * Initialize machine dependent info.  MUST BE CALLED HERE!!!.
  87.      */
  88.     Mach_Init();
  89.     Sync_Init();
  90.  
  91.     /*
  92.      * Initialize the debugger.
  93.      */
  94.     Dbg_Init();
  95.  
  96.     /*
  97.      * Initialize the system module, particularly the fact that there is an
  98.      * implicit DISABLE_INTR on every processor.
  99.      */
  100.     if (main_PrintInitRoutines) {
  101.     Mach_MonPrintf("Calling Sys_Init().\n");
  102.     }
  103.     Sys_Init();
  104.  
  105.     /*
  106.      * Now allow memory to be allocated by the "Vm_BootAlloc" call.  Memory
  107.      * can be allocated by this method until "Vm_Init" is called.  After this
  108.      * then the normal memory allocator must be used.
  109.      */
  110.     if (main_PrintInitRoutines) {
  111.     Mach_MonPrintf("Calling Vm_BootInit().\n");
  112.     }
  113.     Vm_BootInit();
  114.  
  115.     /*
  116.      * Initialize all devices.
  117.      */
  118.     if (main_PrintInitRoutines) {
  119.     Mach_MonPrintf("Calling Dev_Init().\n");
  120.     }
  121.     Dev_Init();
  122.  
  123.     /*
  124.      *  Initialize the mappings of keys to call dump routines.
  125.      *  Must be after Dev_Init. 
  126.      */
  127.     if (main_DoDumpInit) {
  128.     if (main_PrintInitRoutines) {
  129.         Mach_MonPrintf("Calling Dump_Init().\n");
  130.     }
  131.     Dump_Init();
  132.     }
  133.  
  134.     /*
  135.      * Initialize the timer, signal, process, scheduling and synchronization
  136.      * modules' data structures.
  137.      */
  138.     if (main_PrintInitRoutines) {
  139.     Mach_MonPrintf("Calling Proc_Init().\n");
  140.     }
  141.     Proc_Init();
  142.     if (main_PrintInitRoutines) {
  143.     Mach_MonPrintf("Calling Sync_LockStatInit().\n");
  144.     }
  145.     Sync_LockStatInit();
  146.     if (main_PrintInitRoutines) {
  147.     Mach_MonPrintf("Calling Timer_Init().\n");
  148.     }
  149.     Timer_Init();
  150.     if (main_PrintInitRoutines) {
  151.     Mach_MonPrintf("Calling Sig_Init().\n");
  152.     }
  153.     Sig_Init();
  154.     if (main_PrintInitRoutines) {
  155.     Mach_MonPrintf("Calling Sched_Init().\n");
  156.     }
  157.     Sched_Init();
  158.  
  159.     /*
  160.      * Sys_Printfs are not allowed before this point.
  161.      */  
  162.     main_PanicOK++;
  163.     printf("Sprite kernel: %s\n", SpriteVersion());
  164.  
  165.     /*
  166.      * Set up bins for the memory allocator.
  167.      */
  168.     if (main_PrintInitRoutines) {
  169.     Mach_MonPrintf("Calling Fs_Bin\n");
  170.     }
  171.     Fs_Bin();
  172.     if (main_PrintInitRoutines) {
  173.     Mach_MonPrintf("Calling Net_Bin\n");
  174.     }
  175.     Net_Bin();
  176.  
  177.     /*
  178.      * Initialize virtual memory.  After this point must use the normal
  179.      * memory allocator to allocate memory.  If you use Vm_BootAlloc then
  180.      * will get a panic into the debugger.
  181.      */
  182.     if (main_PrintInitRoutines) {
  183.     Mach_MonPrintf("Calling Vm_Init\n");
  184.     }
  185.     Vm_Init();
  186.  
  187.     /*
  188.      * malloc can be called from this point on.
  189.      */
  190.  
  191.     /*
  192.      * Initialize the main process. Must be called before any new 
  193.      * processes are created.
  194.      * Dependencies: Proc_InitTable, Sched_Init, Vm_Init, Mem_Init
  195.      */
  196.     if (main_PrintInitRoutines) {
  197.     Mach_MonPrintf("Calling Proc_InitMainProc\n");
  198.     }
  199.     Proc_InitMainProc();
  200.  
  201.     /*
  202.      * Initialize the network and the routes.  It would be nice if we
  203.      * could call Net_Init earlier so that we can use the debugger earlier
  204.      * but we must call Vm_Init first.  VM could be changed so that we
  205.      * could move the call earlier however.
  206.      */
  207.     if (main_PrintInitRoutines) {
  208.     Mach_MonPrintf("Calling Net_Init\n");
  209.     }
  210.     Net_Init();
  211.     if (main_PrintInitRoutines) {
  212.     Mach_MonPrintf("Calling Net_RouteInit\n");
  213.     }
  214.     Net_RouteInit();
  215.  
  216.     /*
  217.      * Enable server process manager.
  218.      */
  219.     if (main_PrintInitRoutines) {
  220.     Mach_MonPrintf("Calling Proc_ServerInit\n");
  221.     }
  222.     Proc_ServerInit();
  223.  
  224.     /*
  225.      * Initialize the recovery module.  Do before Rpc and after Vm_Init.
  226.      */
  227.     if (main_PrintInitRoutines) {
  228.     Mach_MonPrintf("Calling Recov_Init\n");
  229.     }
  230.     Recov_Init();
  231.  
  232.     /*
  233.      * Initialize the data structures for the Rpc system.  This uses
  234.      * Vm_RawAlloc to so it must be called after Vm_Init.
  235.      * Dependencies: Timer_Init, Vm_Init, Net_Init, Recov_Init
  236.      */
  237.     if (main_PrintInitRoutines) {
  238.     Mach_MonPrintf("Calling Rpc_Init\n");
  239.     }
  240.     Rpc_Init();
  241.  
  242.     /*
  243.      * Configure devices that may or may not exist.  This needs to be
  244.      * done after Proc_InitMainProc because the initialization routines
  245.      * use SetJump which uses the proc table entry for the main process.
  246.      */
  247.     if (main_PrintInitRoutines) {
  248.     Mach_MonPrintf("Calling Dev_Config\n");
  249.     }
  250.     Dev_Config();
  251.  
  252.     /*
  253.      * Initialize profiling after the timer and vm stuff is set up.
  254.      * Dependencies: Timer_Init, Vm_Init
  255.      */
  256.     if (main_DoProf) {
  257.     Prof_Init();
  258.     }
  259.     /*
  260.      *  Allow interrupts from now on.
  261.      */
  262.     if (main_PrintInitRoutines) {
  263.     Mach_MonPrintf("Enabling interrupts\n");
  264.     }
  265.     Mach_MonStartNmi();
  266.     ENABLE_INTR();
  267.  
  268.     if (main_Debug) {
  269.     DBG_CALL;
  270.     }
  271.  
  272.     /*
  273.      * Initialize the fs recovery stuff.
  274.      */
  275.     if (main_PrintInitRoutines && recov_Transparent) {
  276.         Mach_MonPrintf("Calling Fsrecov_InitState.\n");
  277.     }
  278.     if (recov_Transparent) {
  279.     Fsrecov_InitState();
  280.     }
  281.  
  282.     /*
  283.      * Initialize dir op log recovery stuff.
  284.      */
  285.     if (main_PrintInitRoutines && recov_Transparent) {
  286.         Mach_MonPrintf("Calling Fsrecov_DirOpInit.\n");
  287.     }
  288.     if (recov_Transparent) {
  289.     Fsrecov_DirOpInit();
  290.     }
  291.  
  292.  
  293.     /*
  294.      * Sleep for a few seconds to calibrate the idle time ticks.
  295.      */
  296.     Sched_TimeTicks();
  297.  
  298.     /*
  299.      * Start profiling, if desired.
  300.      */
  301.     if (main_DoProf) {
  302.         (void) Prof_Start();
  303.     }
  304.  
  305.     /*
  306.      * Do an initial RPC to get a boot timestamp.  This allows
  307.      * servers to detect when we crash and reboot.  This will set the
  308.      * system clock too, although rdate is usually done from user level later.
  309.      */
  310.     if (main_PrintInitRoutines) {
  311.     Mach_MonPrintf("Call Rpc_Start\n");
  312.     }
  313.     Rpc_Start();
  314.  
  315.     /*
  316.      * Initialize the file system. 
  317.      */
  318.     if (main_PrintInitRoutines) {
  319.     Mach_MonPrintf("Call Fs_Init\n");
  320.     }
  321.     Fs_Init();
  322.  
  323.     /*
  324.      * Before starting up any more processes get a current directory
  325.      * for the main process.  Subsequent new procs will inherit it.
  326.      */
  327.     if (main_PrintInitRoutines) {
  328.     Mach_MonPrintf("Call Fs_ProcInit\n");
  329.     }
  330.     Fs_ProcInit();
  331.     if (main_PrintInitRoutines) {
  332.     Mach_MonPrintf("Bunch of call funcs\n");
  333.     }
  334.     /*
  335.      * Start the clock daemon and the routine that opens up the swap directory.
  336.      */
  337.     Proc_CallFunc(Vm_Clock, (ClientData) NIL, 0);
  338.     Proc_CallFunc(Vm_OpenSwapDirectory, (ClientData) NIL, 0);
  339.  
  340.     /*
  341.      * Start the process that synchronizes the filesystem caches
  342.      * with the data kept on disk.
  343.      */
  344.     Proc_CallFunc(Fsutil_SyncProc, (ClientData) NIL, 0);
  345.  
  346.     /*
  347.      * Create a few RPC server processes and the Rpc_Daemon process which
  348.      * will create more server processes if needed.
  349.      */
  350.     if (main_NumRpcServers > 0) {
  351.     for (i=0 ; i<main_NumRpcServers ; i++) {
  352.         (void) Rpc_CreateServer((int *) &pid);
  353.     }
  354.     }
  355.     (void) Proc_NewProc((Address) Rpc_Daemon, PROC_KERNEL, FALSE, &pid,
  356.     "Rpc_Daemon", FALSE);
  357.     if (main_PrintInitRoutines) {
  358.     Mach_MonPrintf("Creating Proc server procs\n");
  359.     }
  360.  
  361.     /*
  362.      * Create processes  to execute functions.
  363.      */
  364.     (void) Proc_ServerProcCreate(FSCACHE_MAX_CLEANER_PROCS + 
  365.                     VM_MAX_PAGE_OUT_PROCS);
  366.  
  367.     /*
  368.      * Create a recovery process to monitor other hosts.  Can't use
  369.      * Proc_CallFunc's to do this because they can be used up waiting
  370.      * for page faults against down servers.  (Alternatively the VM
  371.      * code could be fixed up to retry page faults later instead of
  372.      * letting the Proc_ServerProc wait for recovery.)
  373.      */
  374.     (void) Proc_NewProc((Address) Recov_Proc, PROC_KERNEL, FALSE, &pid,
  375.             "Recov_Proc", FALSE);
  376.     /*
  377.      * Set up process migration recovery management.
  378.      */
  379.     if (main_PrintInitRoutines) {
  380.     Mach_MonPrintf("Calling Proc_MigInit\n");
  381.     }
  382.     Proc_MigInit();
  383.  
  384.     /*
  385.      * Call the routine to start test kernel processes.
  386.      */
  387.  
  388.     if (main_PrintInitRoutines) {
  389.     Mach_MonPrintf("Calling Main_HookRoutine\n");
  390.     }
  391.     Main_HookRoutine();
  392.  
  393.     /*
  394.      * Print out the amount of memory used.
  395.      */
  396.     printf("MEMORY %d bytes allocated for kernel\n", 
  397.         vmMemEnd - mach_KernStart);
  398.     /*
  399.      * Start up the first user process.
  400.      */
  401.     if (main_PrintInitRoutines) {
  402.     Mach_MonPrintf("Creating Init\n");
  403.     }
  404.     (void) Proc_NewProc((Address) Init, PROC_KERNEL, FALSE, &pid, "Init",
  405.             FALSE);
  406.  
  407.     (void) Sync_WaitTime(time_OneYear);
  408.     printf("Main exiting\n");
  409.     Proc_Exit(0);
  410. }
  411.  
  412.  
  413. /*
  414.  *----------------------------------------------------------------------
  415.  *
  416.  * Init --
  417.  *
  418.  *    This routine execs the init program.
  419.  *
  420.  * Results:
  421.  *    This routine only returns an error if the exec failed.
  422.  *
  423.  * Side effects:
  424.  *    The current process image is overlayed by the init process.
  425.  *
  426.  *----------------------------------------------------------------------
  427.  */
  428. static void
  429. Init()
  430. {
  431.     char        *initArgs[10];
  432.     ReturnStatus    status;
  433.     char        argBuffer[100];
  434.     int            argc;
  435.     Fs_Stream        *dummy;
  436.     char        bootCommand[103];
  437.     char        *ptr;
  438.     int            i;
  439.     int            argLength;
  440.  
  441.     if (main_PrintInitRoutines) {
  442.     Mach_MonPrintf("In Init\n");
  443.     }
  444.     bzero(bootCommand, 103);
  445.     argc = Mach_GetBootArgs(8, 100, &(initArgs[2]), argBuffer);
  446.     if (argc > 0) {
  447.     argLength = (((int) initArgs[argc+1]) + strlen(initArgs[argc+1]) +
  448.             1 - ((int) argBuffer));
  449.     } else {
  450.     argLength = 0;
  451.     }
  452.     if (argLength > 0) {
  453.     initArgs[1] = "-b";
  454.     ptr = bootCommand;
  455.     for (i = 0; i < argLength; i++) {
  456.         if (argBuffer[i] == '\0') {
  457.         *ptr++ = ' ';
  458.         } else {
  459.         *ptr++ = argBuffer[i];
  460.         }
  461.     }
  462.     bootCommand[argLength] = '\0';
  463.     initArgs[2] = bootCommand;
  464.     initArgs[argc + 2] = (char *) NIL;
  465.     } else {
  466.     initArgs[1] = (char *) NIL;
  467.     }
  468.     if (main_AltInit != 0) {
  469.     initArgs[0] = main_AltInit;
  470.     printf("Execing \"%s\"\n", initArgs[0]);
  471.     status = Proc_KernExec(initArgs[0], initArgs);
  472.     printf( "Init: Could not exec %s status %x.\n",
  473.             initArgs[0], status);
  474.     }
  475.     status = Fs_Open(INIT,FS_EXECUTE | FS_FOLLOW, FS_FILE, 0, &dummy);
  476.     if (status != SUCCESS) {
  477.     printf("Can't open %s <0x%x>\n", INIT,status);
  478.     }
  479.     initArgs[0] = INIT;
  480.     status = Proc_KernExec(initArgs[0], initArgs);
  481.     printf( "Init: Could not exec %s status %x.\n",
  482.             initArgs[0], status);
  483.     Proc_Exit(1);
  484. }
  485.  
  486.